home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / umddvi / lib / findpost.c < prev    next >
C/C++ Source or Header  |  1990-10-01  |  2KB  |  91 lines

  1. /*
  2.  * Copyright (c) 1987 University of Maryland Department of Computer Science.
  3.  * All rights reserved.  Permission to copy for any purpose is hereby granted
  4.  * so long as this copyright notice remains intact.
  5.  */
  6.  
  7. #ifndef lint
  8. static char rcsid[] = "$Header: findpost.c,v 2.2 87/06/16 18:27:50 chris Exp $";
  9. #endif
  10.  
  11. /*
  12.  * FindPostAmble - Find the postamble of a DVI file.
  13.  *
  14.  * N.B.: This routine assumes that ftell() returns byte offsets,
  15.  * not magic cookies.
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include "types.h"
  20. #include "dvicodes.h"
  21. #include "fio.h"
  22.  
  23. /*
  24.  * I am making the assumption that 530 bytes will always be enough
  25.  * to find the end of the DVI file.  12 should suffice, as there
  26.  * should be at most seven DVI_FILLER bytes, preceded by the version
  27.  * number, preceded by the four byte postamble pointer; but at least
  28.  * one VMS TeX must pad to a full `sector'.
  29.  */
  30. #ifdef vms
  31. #define POSTSIZE    530    /* make only VMS pay for its errors; */
  32. #else
  33. #define POSTSIZE    16    /* others get to use something reasonable */
  34. #endif
  35.  
  36. long    ftell();
  37.  
  38. FindPostAmble(f)
  39.     register FILE *f;
  40. {
  41.     register long offset;
  42.     register char *p;
  43.     register int i;
  44.     register i32 n;
  45.     char postbuf[POSTSIZE];
  46.  
  47.     /*
  48.      * Avoid fseek'ing beyond beginning of file; it may
  49.      * give odd results.
  50.      */
  51.     fseek(f, 0L, 2);        /* seek to end */
  52.     offset = ftell(f) - POSTSIZE;    /* and compute where to go next */
  53.     if (offset < 0L)        /* but make sure it is positive */
  54.         offset = 0L;
  55.     fseek(f, offset, 0);
  56.     p = postbuf;
  57.     for (i = 0; i < POSTSIZE; i++) {
  58.         *p++ = getc(f);
  59.         if (feof(f)) {
  60.             p--;
  61.             break;
  62.         }
  63.     }
  64.  
  65.     /*
  66.      * Now search backwards for the VERSION byte.  The postamble
  67.      * pointer will be four bytes behind that.
  68.      */
  69.     while (--i >= 0) {
  70.         if (UnSign8(*--p) == DVI_VERSION)
  71.             goto foundit;
  72.         if (UnSign8(*p) != DVI_FILLER)
  73.             break;
  74.     }
  75.     return (-1);        /* cannot find postamble ptr */
  76.  
  77. foundit:
  78.     /*
  79.      * Change offset from the position at the beginning of postbuf
  80.      * to the position of the VERSION byte, and seek to four bytes
  81.      * before that.  Then get a long and use its value to seek to
  82.      * the postamble itself.
  83.      */
  84.     offset += p - postbuf;
  85.     fseek(f, offset - 4L, 0);
  86.     fGetLong(f, n);
  87.     offset = n;
  88.     fseek(f, offset, 0);
  89.     return (0);        /* success */
  90. }
  91.